/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package controllers;

import binding.products.ProductType;
import binding.products.Products;
import com.sun.tools.xjc.util.DOMUtils;
import core.DBEntities;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import utils.CommonUtils;
import utils.DefaultErrorHandler;
import utils.DomUtils;
import utils.UpdateValidate;
import utils.XmlUtils;
import utils.XmlValidate;

public class ProductController extends HttpServlet {

    /** 
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException, SAXException, SQLException, DatatypeConfigurationException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {
            String webPath = getServletContext().getRealPath("/");
            String path = getServletContext().getContextPath();
            String xsdPath = webPath + "WEB-INF/classes/schemas/products.xsd";
            String filePath = webPath + "WEB-INF/XmlDoc/Products.xml";
            String xslPath = webPath + "WEB-INF/XslDoc/Management.xsl";
            String action = request.getParameter("action");

            if (action.equals("PRODUCT_UPDATE")) {
                String name = request.getParameter("name");
                //String img = request.getParameter("img");
                String des = request.getParameter("des");
                String price = request.getParameter("price");
                String proid = request.getParameter("proid");

                DefaultErrorHandler handler = new DefaultErrorHandler();
                UpdateValidate validator = UpdateValidate.Instance(filePath, xsdPath);

                //setup parameter
                LinkedHashMap<String, String> keys = new LinkedHashMap<String, String>();
                keys.put("Id", proid);
                LinkedHashMap<String, String> pros = new LinkedHashMap<String, String>();
                pros.put("Name", name);
                // pros.put("ImageUrl", img);
                pros.put("Description", des);
                pros.put("Price", price);

                //do validate
                Source source = validator.updateOnValidateSource(handler, "Product", keys, pros);
                if (handler.isError()) {
                    String pro = "<?xml version='1.0' encoding='UTF-8'?>";
                    pro += "<error>" + handler.getErrorMessage() + "</error>";
                    response.setContentType("text/xml");
                    out.write(pro);
                } else {
                    Object proObj = XmlUtils.unMarshalXml(xsdPath, source, Products.class);
                    if (proObj instanceof Products) {
                        Products pro = (Products) proObj;

                        ProductType proType = null;
                        for (ProductType pt : pro.getProduct()) {
                            if (String.valueOf(pt.getId().intValue()).equals(proid)) {
                                proType = pt;
                            }
                        }
                        if (DBEntities.saveProduct(proType)) {
                            //update xml
                            XmlUtils.marshalXml(pro, filePath);
                            String responseString = XmlUtils.transformToString(xslPath, source);
                            out.write(responseString);
                        }
                    }
                }
            } else if (action.equals("PRODUCT_ACTIVATION")) {
                String proid = request.getParameter("proid");
                Object obj = XmlUtils.unMarshalXml(xsdPath, filePath, Products.class);
                if (obj != null && obj instanceof Products) {
                    Products proList = (Products) obj;
                    ProductType proType = null;
                    for (ProductType pt : proList.getProduct()) {
                        if (proid.equals(String.valueOf(pt.getId().intValue()))) {
                            proType = pt;
                        }
                    }
                    if (proType != null) {
                        proType.setIsActive(!proType.isIsActive());
                    }
                    //save to db
                    if (DBEntities.saveProduct(proType)) {
                        XmlUtils.marshalXml(proList, filePath);
                        Map<String, Object> params = new LinkedHashMap<String, Object>();
                        params.put("type", "inproduct");
                        String result = XmlUtils.transformToString(webPath + "WEB-INF/XslDoc/Management.xsl", webPath + "WEB-INF/XmlDoc/Products.xml", params);


//                        String sResponse = XmlUtils.transformToString(xslPath, jaxbSource);
                        out.write(result);
                    }
                }
            } else if (action.equals("PRODUCT_ADD")) {
                String name = request.getParameter("name");
                String imageurl = request.getParameter("imageurl");
                String price = request.getParameter("price");
                String description = request.getParameter("description");
                //Restaurant Detail
                Map<String, Object> properties = new LinkedHashMap<String, Object>();
                properties.put("Name", name);
                properties.put("ImageURL", imageurl);
                properties.put("Description", description);
                properties.put("Price", price);
                properties.put("IsActive", true);

                //need to validate here
                Node doc = DomUtils.buildDomTree("http://xml.netbeans.org/schema/products", "Products", "Product", properties);
                DefaultErrorHandler handler = new DefaultErrorHandler();
                XmlValidate.validate(xsdPath, new DOMSource(doc), handler);
                if (name == null || name.equals("") || name.split(" ").equals("")) {
                    String res = "<?xml version='1.0' encoding='UTF-8'?>";
                    res += "<errorName>" + "Name is required" + "</errorName>";
                    response.setContentType("text/xml");
                    out.write(res);
                } else if (handler.isError()) {
                    String res = "<?xml version='1.0' encoding='UTF-8'?>";
                    res += "<errorPrice>" + "Price is invalid" + "</errorPrice>";
                    response.setContentType("text/xml");
                    out.write(res);
                } else {
                    //after validating->save to db
                    ProductType proType = new ProductType();
                    //resType.setId(BigInteger.ZERO);
                    proType.setName(name);
                    proType.setImageURL(imageurl);
                    proType.setPrice(BigDecimal.valueOf(Double.parseDouble(price)));
                    proType.setDescription(description);
                    proType.setIsActive(true);


                    if (DBEntities.addProduct(proType)) {

                        Products listproduct = DBEntities.getProducts();
                        XmlUtils.marshalXml(listproduct, filePath);
                        Map<String, Object> params = new LinkedHashMap<String, Object>();
                        params.put("type", "inproduct");
                        String result = XmlUtils.transformToString(webPath + "WEB-INF/XslDoc/Management.xsl", webPath + "WEB-INF/XmlDoc/Products.xml", params);
                        out.write(result);
                    }
                }

            }
        } finally {
            out.close();
        }
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /** 
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        try {
            processRequest(request, response);
        } catch (DatatypeConfigurationException ex) {
            Logger.getLogger(ProductController.class.getName()).log(Level.SEVERE, null, ex);

        } catch (SAXException ex) {
            Logger.getLogger(ProductController.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SQLException ex) {
            Logger.getLogger(ProductController.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /** 
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        try {
            processRequest(request, response);
        } catch (DatatypeConfigurationException ex) {
            Logger.getLogger(ProductController.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SAXException ex) {
            Logger.getLogger(ProductController.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SQLException ex) {
            Logger.getLogger(ProductController.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /** 
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>
}
